package com.navi.loaddata.loadUnit;

import java.net.InetAddress;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.navi.loaddata.core.gpEntity.*;
import com.navi.loaddata.core.mysqlEntity.MBisDataD;
import com.navi.loaddata.core.repository.impl.MySqlRepositoryImpl;
import com.navi.loaddata.loadhis.LoadProductHis;
import com.navi.loaddata.utils.SqlUtil;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.navi.loaddata.core.entity.CtProductLocationHis;
import com.navi.loaddata.core.entity.MaxTime;
import com.navi.loaddata.core.entity.OCGlassId;
import com.navi.loaddata.core.repository.impl.GreenPlumRepositoryImpl;
import com.navi.loaddata.utils.JacksonUtil;
import com.navi.loaddata.utils.JdbcUtil;
import com.navi.loaddata.utils.pgJDBCUtils;

@Service
@Transactional(transactionManager = "secondaryPlatformTransactionManager")
public class LoadProductProcLocationHisOnlyOutTime {

	private static final Logger logger = LoggerFactory.getLogger(LoadProductProcLocationHisOnlyOutTime.class);
	@Autowired
	private GreenPlumRepositoryImpl dao2;

	@Autowired
	private MySqlRepositoryImpl mysqlDao;

	@Autowired
	private AmqpTemplate rabbitTemplate;

	@Value("${etl.unitStart}")
	private String start;

	@Value("${etl.unitEnd}")
	private String end;

//	 @Scheduled(cron = "* */15 * * * ?")
	public void loadprodHis() {
		try {

//			start = "2018-04-24 21:19:06";
//			end = "2018-04-24 22:29:06";
			long startTime = System.currentTimeMillis();
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddHHmmss");
			Timestamp sysTimestamp = null;
			QueryRunner ora = pgJDBCUtils.getQueryRunner_ora();
			List<MaxTime> a = ora.query("select max(out_timestamp) as time from wpp_aunit_his",
					new BeanListHandler<MaxTime>(MaxTime.class));
			List<MaxTime> c = ora.query("select max(out_timestamp) as time from wpp_cunit_his",
					new BeanListHandler<MaxTime>(MaxTime.class));
			List<MaxTime> f = ora.query("select max(out_timestamp) as time from wpp_funit_his",
					new BeanListHandler<MaxTime>(MaxTime.class));
			List<Long> arrList = new ArrayList<Long>();
			if (a.get(0).getTime() != null && a.size() > 0) {
				arrList.add(a.get(0).getTime().getTime());
			}
			if (c.get(0).getTime() != null && c.size() > 0) {
				arrList.add(c.get(0).getTime().getTime());
			}
			if (f.get(0).getTime() != null && f.size() > 0) {
				arrList.add(f.get(0).getTime().getTime());
			}
			logger.info("获取unit表max(out_timestamp)：a:{},b:{},c:{}",arrList.get(0),arrList.get(1),arrList.get(2));
			if (arrList.size() > 0) {
				long[] arr = new long[arrList.size()];
				for (int i = 0, j = arrList.size(); i < j; i++) {
					arr[i] = arrList.get(i);
				}
				long temp = 0;
				for (int i = 0; i < arr.length - 1; i++) {
					for (int j = 0; j < arr.length - 1 - i; j++) {
						if (arr[j] > arr[j + 1]) {
							temp = arr[j];
							arr[j] = arr[j + 1];
							arr[j + 1] = temp;
						}
					}
				}
				sysTimestamp = Timestamp
						.valueOf(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(arr[arr.length - 1])));
			}
			QueryRunner qr_ora = JdbcUtil.getQueryRunner_ora();
			String sql = "";
			String s1 = "";
			String s2 = "";
			String sql2 = "";
			Calendar calendar = Calendar.getInstance();
			if (sysTimestamp != null) {
				s1 = sysTimestamp.toString().substring(0, 19);
				// s1 = Timestamp.valueOf("2018-01-16 00:00:00").toString();
			} else {
				 s1 = Timestamp.valueOf("2017-12-01 18:00:27").toString();
			}
			Date addTime = sdf.parse(s1);
			calendar.setTime(addTime);
//			calendar.add(Calendar.MINUTE, 3);
			calendar.add(Calendar.HOUR, 1);
			s2 = sdf.format(calendar.getTime());

			if (!("null").equals(start) && !("null").equals(end)) {
				logger.info("开始补数据时间",start);
				logger.info("结束补数据时间",end);
				s1 = Timestamp.valueOf(start.substring(0, 19)).toString();
				s2 = Timestamp.valueOf(end.substring(0, 19)).toString();
			}
			if(!sdf.parse(s2).before(new Date())){
				return;
			}
			List<MProdD> mProdDS = dao2.list(MProdD.class, "from MProdD");
			HashMap<String, Integer> prods = new HashMap<String, Integer>();
			for (MProdD mProdD : mProdDS) {
				String shopId = mProdD.getShopId();
				String prodId = mProdD.getProdId();
				int prodKey = mProdD.getProdKey();
				String key = shopId + prodId;
				prods.put(key, prodKey);
			}
			List<MOpeD> mOpeDS = dao2.list(MOpeD.class, "from MOpeD");
			HashMap<String, Integer> opes = new HashMap<String, Integer>();
			for (MOpeD mOpeD : mOpeDS) {
				String key = mOpeD.getOpeId();
				int value = mOpeD.getOpeKey();
				opes.put(key, value);
			}
			List<MShopD> mShopDS = dao2.list(MShopD.class, "from MShopD");
			HashMap<String, Integer> shops = new HashMap<String, Integer>();
			for (MShopD mShopD : mShopDS) {
				String key = mShopD.getShopId();
				int value = mShopD.getShopKey();
				shops.put(key, value);
			}

			long total = 0L;
			long startTrackOutTime= System.currentTimeMillis();
			while (true) {
				Date endDate = sdf.parse(s2);
				Date nowDate = new Date();
				if(endDate.after(nowDate)){
					logger.info("endDate:{},now:{} 大于当前时间：job结束。",endDate,nowDate);
					break;
				}
				sql = "SELECT" + "  TrackOut.PRODUCTNAME AS glass_id,"
						+ "  TrackOut.PROCESSOPERATIONNAME AS ope_id," + "  TrackOut.SUBFACTORYNAME AS shop_id,"
						+ " TrackOut.PRODUCTSPECNAME AS prod_id," + "  TrackOut.LINENAME AS eqpt_id,"
						+ "  TrackOut.SUBUNITNAME AS sub_eqpt_id," + "  TrackOut.UNITNAME AS unit_eqpt_id,"
						+ "  TrackOut.PORTNAME AS eqpt_port_id," + "  TrackOut.LINERECIPENAME AS recipe_id,"
						+ " TrackOut.BCRECIPEID AS ac_recipe_id," + " TrackOut.TRACELEVEL AS trace_level,"
						+ "  TrackOut.EVENTTIME AS out_timestamp," + "  TrackOut.UPDATETIME AS MES_TIMESTAMP,"
						+ "  TrackOut.LOTNAME AS lot_id," + "  TrackOut.CARRIERNAME AS carrier_name,"
						+ "  TrackOut.LINKKEY AS link_key," + "  TrackOut.ProductSpecVersion AS prod_spec_ver,"
						+ "  TrackOut.POSITION" + " FROM" + "  MES_CT_PRODUCTLOCATIONHIST TrackOut" + " WHERE"
						+ "  TrackOut.EVENTNAME='ProductOut'" + " and TrackOut.PROCESSOPERATIONNAME is not null"
						+ " and TrackOut.SUBFACTORYNAME is not null" + "  AND TrackOut.UNITNAME is not null"
//						+ " AND TrackOut.UPDATETIME >= to_date('" + s1.substring(0, 19) + "','yyyy/mm/dd HH24:MI:SS')\n"
//						+ "  AND TrackOut.UPDATETIME < to_date('" + s2.substring(0, 19) + "','yyyy/mm/dd HH24:MI:SS')"
						+" AND TrackOut.TIMEKEY >='"+sdf2.format(sdf.parse(s1.substring(0, 19)))+"'"
						+" AND TrackOut.TIMEKEY <'"+sdf2.format(sdf.parse(s2.substring(0, 19)))+"'";
//						+ " order by glass_id,ope_id,shop_id,trace_level,unit_eqpt_id,eqpt_id ";
				List<CtProductLocationHis> cTproductHisList = qr_ora.query(sql,
						new BeanListHandler<CtProductLocationHis>(CtProductLocationHis.class));


	/*			HashMap<String, CtProductLocationHis> trackOutMap = new HashMap<String, CtProductLocationHis>();
				for (CtProductLocationHis oc : cTproductHisList) {
					String shopId = oc.getShop_id();
					String glassId = oc.getGlass_id();
					String eqptId = oc.getEqpt_id();
					String unitId = oc.getUnit_eqpt_id();
					String recipeId = oc.getRecipe_id();
					String opeId = oc.getOpe_id();
					String key = shopId + glassId  + eqptId +unitId +recipeId + opeId;
					trackOutMap.put(key, oc);
				}*/
				long endWhileTime = System.currentTimeMillis();
				long whileMinute = (endWhileTime - startTrackOutTime) / 1000;


				logger.info("LoadProductProcLocationHisOnlyOutTime  cTproductHisList 执行时间：{} s ，TrackOut.eventtime :{}---{},unit查询出Out数量：:{}",whileMinute,s1.substring(0, 19),s2.substring(0, 19),cTproductHisList.size());

				long startTrackInTime= System.currentTimeMillis();

				Date beforeTime = sdf.parse(s1);
				calendar.setTime(beforeTime);
				calendar.add(Calendar.MINUTE, -30);
				String s3 = sdf.format(calendar.getTime());
				sql2 = "SELECT\n" + "  TrackIn.PRODUCTNAME AS glass_id,\n"
						+ "  TrackIn.PROCESSOPERATIONNAME AS ope_id,\n" + "  TrackIn.SUBFACTORYNAME AS shop_id,\n"
						+ " TrackIn.PRODUCTSPECNAME AS prod_id,\n" + "  TrackIn.LINENAME AS eqpt_id,\n"
						+ "  TrackIn.SUBUNITNAME AS sub_eqpt_id,\n" + "  TrackIn.UNITNAME AS unit_eqpt_id,\n"
						+ "  TrackIn.PORTNAME AS eqpt_port_id,\n" + "  TrackIn.LINERECIPENAME AS recipe_id,\n"
						+ " TrackIn.BCRECIPEID AS ac_recipe_id,\n" + " TrackIn.TRACELEVEL AS trace_level,\n"
						+ "  TrackIn.EVENTTIME AS in_timestamp,\n" + "  TrackIn.UPDATETIME AS MES_TIMESTAMP,\n"
						+ "  case when TrackIn.SUBFACTORYNAME = 'OC' THEN TrackIn.GROUPNAME ELSE TrackIn.LOTNAME END  AS lot_id,\n"
						+ "  TrackIn.CARRIERNAME AS carrier_name,\n"
						+ "  TrackIn.POSITION\n" + "FROM\n" + "  MES_CT_PRODUCTLOCATIONHIST TrackIn\n" + "WHERE\n"
						+ "  TrackIn.EVENTNAME='ProductIn'\n" + " and TrackIn.PROCESSOPERATIONNAME is not null\n"
						+ " and TrackIn.TRACELEVEL is not null\n" + "  AND TrackIn.LINENAME is not null\n"
//						+ " AND TrackIn.UPDATETIME >= to_date('" + s3.substring(0, 19) + "','yyyy/mm/dd HH24:MI:SS')\n"
//						+ "  AND TrackIn.UPDATETIME < to_date('" + s2.substring(0, 19) + "','yyyy/mm/dd HH24:MI:SS')"
						+" AND TrackIn.TIMEKEY >='"+sdf2.format(sdf.parse(s3.substring(0, 19)))+"'"
						+" AND TrackIn.TIMEKEY <'"+sdf2.format(sdf.parse(s2.substring(0, 19)))+"'";
//						+ "  order by glass_id,ope_id,shop_id,trace_level,unit_eqpt_id,eqpt_id ";
				List<CtProductLocationHis> lists = qr_ora.query(sql2,
						new BeanListHandler<CtProductLocationHis>(CtProductLocationHis.class));

		/*		HashMap<String, CtProductLocationHis> trackInMap = new HashMap<String, CtProductLocationHis>();
				for (CtProductLocationHis list : lists) {
					String shopId = list.getShop_id();
					String glassId = list.getGlass_id();
					String eqptId = list.getEqpt_id();
					String unitId = list.getUnit_eqpt_id();
					String recipeId = list.getRecipe_id();
					String opeId = list.getOpe_id();
					String key = shopId + glassId  + eqptId +unitId +recipeId + opeId;
					trackInMap.put(key, list);
				}*/



				long endlistsTime = System.currentTimeMillis();
				long listsMinute = (endlistsTime - startTrackInTime) / 1000;
				logger.info("LoadProductProcLocationHisOnlyOutTime  lists sql 执行时间：{} s ，TrackIn.eventtime :{}---{},unit查询出Out数量：:{}",listsMinute,s3.substring(0, 19),s2.substring(0, 19),lists.size());

				//获取cTproductHisList的所有GlassId,以获取mes表中的tft,cf  glass_id
				 Set<String> glassIdSet= ConcurrentHashMap.newKeySet();
				long startForTime= System.currentTimeMillis();
				String glassFlg = "";


				long outTime ;
				long flag ;
				long reduce ;
				long inTime ;
				List<CtProductLocationHis> 	ctProductLocationHisList=new ArrayList<>();
				for (CtProductLocationHis out : cTproductHisList) {
					 glassIdSet.add(out.getGlass_id().substring(0,10));
					Timestamp out_timestamp = out.getOut_timestamp();
					outTime = out_timestamp.getTime();
					flag = 9999999999L;
					reduce = 0L;
					if (StringUtils.isBlank(glassFlg)){
						glassFlg = out.getGlass_id()+"-"+out.getOpe_id()+"_"+out.getShop_id()+"-"+out.getTrace_level()+"_"+out.getUnit_eqpt_id()+"-"+out.getEqpt_id();// TODO 赋值当前
						ctProductLocationHisList =lists.stream().filter(in ->
								out.getGlass_id().equals(in.getGlass_id()) && out.getOpe_id().equals(in.getOpe_id())
										&& out.getShop_id().equals(in.getShop_id()) && in.getTrace_level().equals(out.getTrace_level())
										&& out.getUnit_eqpt_id().equals(in.getUnit_eqpt_id()) && in.getEqpt_id().equals(out.getEqpt_id())
										&& (out.getOut_timestamp().getTime() > in.getIn_timestamp().getTime())).collect(Collectors.toList());
					}
					// 获取cTproductHisList，order by
					if((out.getGlass_id()+"-"+out.getOpe_id()+"_"+out.getShop_id()+"-"+out.getTrace_level()+"_"+out.getUnit_eqpt_id()+"-"+out.getEqpt_id()).equals(glassFlg)){

					}else{
						glassFlg = out.getGlass_id()+"-"+out.getOpe_id()+"_"+out.getShop_id()+"-"+out.getTrace_level()+"_"+out.getUnit_eqpt_id()+"-"+out.getEqpt_id();
					 	ctProductLocationHisList =lists.stream().filter(in ->
						out.getGlass_id().equals(in.getGlass_id()) && out.getOpe_id().equals(in.getOpe_id())
								&& out.getShop_id().equals(in.getShop_id()) && in.getTrace_level().equals(out.getTrace_level())
								&& out.getUnit_eqpt_id().equals(in.getUnit_eqpt_id()) && in.getEqpt_id().equals(out.getEqpt_id())
								&& (out.getOut_timestamp().getTime() > in.getIn_timestamp().getTime())).collect(Collectors.toList());
					}

					for (CtProductLocationHis in : ctProductLocationHisList) {
						Timestamp in_timestamp = in.getIn_timestamp();
						 inTime = in_timestamp.getTime();
						try{
							/*if (out.getGlass_id().equals(in.getGlass_id()) && out.getOpe_id().equals(in.getOpe_id())
									&& out.getShop_id().equals(in.getShop_id())
									&& in.getTrace_level().equals(out.getTrace_level())
									&& out.getUnit_eqpt_id().equals(in.getUnit_eqpt_id())
									&& in.getEqpt_id().equals(out.getEqpt_id())
									&& outTime > inTime) {*/
//							System.out.println(out.getGlass_id()+"终于进内循环啦");
								reduce = outTime - inTime;
//							System.out.println("相差时间"+reduce);
								if (reduce < flag) {
									out.setIn_timestamp(in_timestamp);
									out.setRecipe_id(in.getRecipe_id());
									out.setAc_recipe_id(in.getAc_recipe_id());
									flag = reduce;
//								System.out.println("flag重新赋值"+flag);
								}
				//			}

						}catch(Exception e){
							ObjectMapper mapper = new ObjectMapper();
							String jsonOut = mapper.writeValueAsString(out);
							String jsonIn = mapper.writeValueAsString(in);
							logger.error("error message jsonOut:{}",jsonOut);
					        logger.error("error message jsonIn:{}",jsonIn);
						}

					}
				}
				long endForTime = System.currentTimeMillis();
				long forminute = (endForTime - startForTime)  / 1000;
				logger.info("LoadProductProcLocationHisOnlyOutTime  TrackOut,TrackIn,总循环时间：{} s,glassIdSet.size():{} ",forminute,glassIdSet.size());
				long startOCsTime= System.currentTimeMillis();
				HashMap<String, String> ocs = new HashMap<String, String>();
				List<OCGlassId> OCs=new ArrayList<>();
				if (cTproductHisList != null && cTproductHisList.size() > 0) {
					StringBuffer sqlMes=new StringBuffer();
					sqlMes.append(" select  tft_glass_id AS tftGlassId, cf_glass_id AS cfGlassId,");
					sqlMes.append(" panel_id as glassId from wpp_sht_info  ");
					sqlMes.append(" where (tft_glass_id IS NOT NULL or cf_glass_id IS NOT NULL) ");
					String panelInCondition = SqlUtil.set2InCondition(glassIdSet,"panel_id");
					if(glassIdSet.size()>0 && glassIdSet.size()<1000){
						sqlMes.append(" and panel_id in(").append(panelInCondition).append(") ");
					}else if(glassIdSet.size()>= 1000){
						sqlMes.append(" and( ").append(panelInCondition).append("  )");
					}
					try{
						OCs= ora.query(sqlMes.toString(), new BeanListHandler<OCGlassId>(OCGlassId.class));
					}catch (Exception e){
						logger.error("从wpp_sht_info获取glass对应tft，cf glass_id 失败，{}",e.getLocalizedMessage());
					}
					long endOCsTime = System.currentTimeMillis();
					long OCsminute = (endOCsTime - startOCsTime) / 1000;
					logger.info("LoadProductProcLocationHisOnlyOutTime  从wpp_sht_info获取glass对应tft，cf glass_id时间：{} s ",OCsminute);

					for (OCGlassId oc : OCs) {
						String cfGlassId = oc.getCfGlassId();
						String glassId = oc.getGlassId().substring(0,10);
						String tftGlassId = oc.getTftGlassId();
						String key = glassId;
						String value = cfGlassId + "-" + tftGlassId;
						ocs.put(key, value);
					}

					String hql = "from MHourD";
					final List<MHourD> mHourDList = dao2.find(MHourD.class, hql);
					Map<String,String> shfTimeMap =getShfTimeProc();
					Map<String,String> shfIdMap = getShfMap();
//					total = 2L;
					total = cTproductHisList.size();
					long startSaveTime= System.currentTimeMillis();
								cTproductHisList.forEach(cTproductHis -> {
						if ("A".equalsIgnoreCase(cTproductHis.getShop_id().substring(0, 1))) {
							 saveAUnit(cTproductHis, shops, opes, prods,mHourDList,shfTimeMap,shfIdMap);
						} else if ("O".equalsIgnoreCase(cTproductHis.getShop_id().substring(0, 1))) {
							 saveCUnit(cTproductHis, shops, opes, prods, ocs,mHourDList,shfTimeMap,shfIdMap);
						} else if ("C".equalsIgnoreCase(cTproductHis.getShop_id().substring(0, 1))) {
							 saveFUnit(cTproductHis, shops, opes, prods,mHourDList,shfTimeMap,shfIdMap);
						}
					});
					long endSaveTime = System.currentTimeMillis();
					long saveMinute = (endSaveTime - startSaveTime) / 1000;
					logger.info("LoadProductProcLocationHisOnlyOutTime  saveUnit时间：{} s ",saveMinute);

				}
				Date date = sdf.parse(s2);
				String s = sdf.format(date);
//				System.out.println(s);
				long endTime = System.currentTimeMillis();
				long minute = (endTime - startTime)  / 1000;

//				System.out.println("unit执行了：" + minute + "分钟");
				// if ((endTime - date.getTime()) <= (10 * 60 * 1000) ||
				// (endTime - startTime) >= (2 * 60 * 1000)) {
				if ( total > 1000) {
					logger.info("job结束：unit执行了：{} s",minute);
					break;
				}

				// }
				s1 = s2;
				Date newTime = sdf.parse(s1);
				calendar.setTime(newTime);
//				calendar.add(Calendar.MINUTE, 3);
				calendar.add(Calendar.HOUR, 1);
				s2 = sdf.format(calendar.getTime());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void saveFUnit(CtProductLocationHis cTproductHis, HashMap<String, Integer> shops,
			HashMap<String, Integer> opes, HashMap<String, Integer> prods,List<MHourD> mHourDList,Map<String,String> shfTimeMap,Map<String,String> shfIdMap) {

		String prod_id = cTproductHis.getProd_id();
		String ope_id = cTproductHis.getOpe_id();
		String shop_id = cTproductHis.getShop_id();
		String sub_eqpt_id = cTproductHis.getSub_eqpt_id();
		String glass_id = cTproductHis.getGlass_id();

		try {
			int prodKey = 0;
			String proKey = shop_id + prod_id;
			Integer pKey = prods.get(proKey);
			if (prod_id == null || prod_id.length() <= 0) {
				prod_id = "no";
			}
			if (pKey != null && pKey > 0) {
				prodKey = pKey;
			}
			int opeKey = 0;
			Integer oKey = opes.get(ope_id);
			if (oKey != null && oKey > 0) {
				opeKey = oKey;
			}
			int shopKey = 0;
			Integer sKey = shops.get(shop_id);
			if (sKey != null && sKey > 0) {
				shopKey = sKey;
			}
			WppFunitHis wppFUnit = new WppFunitHis();
			// base_id
			if (glass_id.length() == 10) {
				wppFUnit.setBaseId("G");
			} else if (glass_id.length() == 12) {
				wppFUnit.setBaseId("P");
			} else {
				return;
			}

			String unq_seq_id = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
			if (sub_eqpt_id == null || sub_eqpt_id == "") {
				wppFUnit.setSubEqptId("no");
			} else {
				wppFUnit.setSubEqptId(sub_eqpt_id);
			}
			wppFUnit.setProdKey(prodKey);
			wppFUnit.setOpeKey(opeKey);
			wppFUnit.setShopKeyFk(shopKey);
			wppFUnit.setUnqSeqId(unq_seq_id);
			wppFUnit.setEtlTimestamp(Timestamp.valueOf(LocalDateTime.now()));
			wppFUnit.setEtlEventNode(InetAddress.getLocalHost().getHostAddress());
			wppFUnit.setEtlEventName(InetAddress.getLocalHost().getHostName());
			wppFUnit.setEtlEvtSeqId(unq_seq_id);
			wppFUnit.setGlassId(glass_id);
			wppFUnit.setOpeId(ope_id);
			wppFUnit.setShopId(shop_id);
			wppFUnit.setProdId(prod_id);
			wppFUnit.setEqptId(cTproductHis.getEqpt_id());
			wppFUnit.setUnitEqptId(cTproductHis.getUnit_eqpt_id());
			wppFUnit.setEqptPortId(cTproductHis.getEqpt_port_id());
			wppFUnit.setRecipeId(cTproductHis.getRecipe_id());
			wppFUnit.setAcRecipeId(cTproductHis.getAc_recipe_id());
			wppFUnit.setEvtCate("etl");
			wppFUnit.setEvtUsr("etl");
			wppFUnit.setInTimestamp(cTproductHis.getIn_timestamp());
			wppFUnit.setOutTimestamp(cTproductHis.getOut_timestamp());
			wppFUnit.setEvtTimestamp(cTproductHis.getOut_timestamp());
			// evt_note
			wppFUnit.setMesTimestamp(cTproductHis.getMes_timestamp());
			wppFUnit.setLotId(cTproductHis.getLot_id());
			wppFUnit.setCarrierName(cTproductHis.getCarrier_name());
			wppFUnit.setPosition(cTproductHis.getPosition());
			wppFUnit.setTraceLevel(cTproductHis.getTrace_level());
			wppFUnit.setProd_spec_ver(cTproductHis.getProd_spec_ver());
			wppFUnit.setLink_key(cTproductHis.getLink_key());


			wppFUnit.setOpeTblName("wpp_funit_his");

			//modify by LynnSea

			Timestamp trackOutTimestamp = wppFUnit.getOutTimestamp();

			//得到mysql中设定的白班和夜班的开始结束时间
			// final String shfName = getShfNameProc(trackOutTimestamp);
			final String shfName =isDayShift(trackOutTimestamp, shfTimeMap.get("strDayShiftStartTime"),
					shfTimeMap.get("strDayShiftEndTime")) ? "Day" : "Night";

		//	String hql;
			final String shopId = "2";

			//从m_shf_d表中查询出来shfId和shfKey ,并赋值shfKeyFk , shfId
			String shfId =shfIdMap.get(shfName+"_"+shopId);
			wppFUnit.setShfId(shfId);
			/*hql = "from MShfD where shfName = '" + shfName + "' and shop_key =' " + shopId + "'";
			final MShfD mShfD = dao2.uniqueResult(MShfD.class, hql);
			if (mShfD != null) {
				wppFUnit.setShfId(mShfD.getShfId());
//                wppAshtOpe.setShfKeyFk(mShfD.getShfKey());
			}*/

			//判断日期归属，白班和夜班存的是同一天
			//caldDate,caldKey

			final LocalDateTime localDateTime = trackOutTimestamp.toLocalDateTime();
			LocalDate localDate = LocalDate.ofYearDay(localDateTime.getYear(), localDateTime.getDayOfYear());

			if (StringUtils.equalsIgnoreCase(shfName, "Night")) {
				if (localDateTime.getHour() < 12 ) {
					localDate = localDate.plusDays(-1);
				}
			}
			wppFUnit.setCaldDate(java.sql.Date.valueOf(localDate));

			//判断小时，
			//并赋值给hourKeyFk,hourId

			/*hql = "from MHourD";
			final List<MHourD> mHourDList = dao2.find(MHourD.class, hql);*/
			final MHourD mHourD = calcHourProc(trackOutTimestamp, mHourDList);
			if (mHourD != null) {
				wppFUnit.setHourKeyFk(mHourD.getHourKey());
			}
			try {
				rabbitTemplate.convertAndSend("qmsExchange", "wpp_funit_his", JacksonUtil.toJSONStr(wppFUnit));
			} catch (Exception e) {
				e.printStackTrace();
			}
//			 dao2.update(wppFUnit);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void saveCUnit(CtProductLocationHis cTproductHis, HashMap<String, Integer> shops,
			HashMap<String, Integer> opes, HashMap<String, Integer> prods, HashMap<String, String> ocs,List<MHourD> mHourDList,Map<String,String> shfTimeMap,Map<String,String> shfIdMap) {
		String prod_id = cTproductHis.getProd_id();
		String ope_id = cTproductHis.getOpe_id();
		String shop_id = cTproductHis.getShop_id();
		String sub_eqpt_id = cTproductHis.getSub_eqpt_id();
		String glass_id = cTproductHis.getGlass_id();
		String eqpt_id = cTproductHis.getEqpt_id();
//		System.out.println("进入C");
		try {
			int prodKey = 0;
			String proKey = shop_id + prod_id;
			Integer pKey = prods.get(proKey);
			if (prod_id == null || prod_id.length() <= 0) {
				prod_id = "no";
			}
			if (pKey != null && pKey > 0) {
				prodKey = pKey;
			}
			int opeKey = 0;
			Integer oKey = opes.get(ope_id);
			if (oKey != null && oKey > 0) {
				opeKey = oKey;
			}
			int shopKey = 0;
			Integer sKey = shops.get(shop_id);
			if (sKey != null && sKey > 0) {
				shopKey = sKey;
			}
			WppCunitHis wppCUnit = new WppCunitHis();
			// base_id
			if (glass_id.length() == 10) {
				wppCUnit.setBaseId("G");
			} else if (glass_id.length() == 12) {
				wppCUnit.setBaseId("P");
			} else {
				return;
			}

			/*
			 * List<OCGlassId> OCs = qr_ora.query(
			 * "select ARRAYGLASSNAME AS tftGlassId, CFGLASSNAME AS cfGlassId from MES_PRODUCTHISTORY "
			 * +
			 * "where SUBFACTORYNAME='OC' AND PRODUCTNAME = ? and OLDPROCESSOPERATIONNAME=? and MACHINENAME=? "
			 * + "AND ARRAYGLASSNAME IS NOT NULL AND CFGLASSNAME IS NOT NULL",
			 * new BeanListHandler<OCGlassId>(OCGlassId.class),
			 * glass_id,ope_id,eqpt_id);
			 * 
			 * if(OCs!=null&&OCs.size()>0){ String cfGlassId =
			 * OCs.get(0).getCfGlassId(); String tftGlassId =
			 * OCs.get(0).getTftGlassId(); wppCUnit.setTftGlassId(tftGlassId);
			 * wppCUnit.setCfGlassId(cfGlassId); }
			 */
			//String ock = shop_id + glass_id + ope_id + eqpt_id;
			String ock = glass_id.substring(0,10) ;
			String value = ocs.get(ock);
			if(value!=null&&value.contains("-")){
				//System.out.println(value);
				String[] split = value.split("-");
				wppCUnit.setTftGlassId(split[1]);
				wppCUnit.setCfGlassId(split[0]);
			}
			String unq_seq_id = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);

			if (sub_eqpt_id == null || sub_eqpt_id == "") {
				wppCUnit.setSubEqptId("---");
			} else {
				wppCUnit.setSubEqptId(sub_eqpt_id);
			}

			wppCUnit.setProdKey(prodKey);
			wppCUnit.setOpeKey(opeKey);
			wppCUnit.setShopKeyFk(shopKey);
			wppCUnit.setUnqSeqId(unq_seq_id);
			wppCUnit.setEtlTimestamp(Timestamp.valueOf(LocalDateTime.now()));
			wppCUnit.setEtlEventNode(InetAddress.getLocalHost().getHostAddress());
			wppCUnit.setEtlEventName(InetAddress.getLocalHost().getHostName());
			// etl_evt_seq_id
			wppCUnit.setEtlEvtSeqId(unq_seq_id);
			wppCUnit.setGlassId(glass_id);
			wppCUnit.setOpeId(ope_id);
			wppCUnit.setShopId(shop_id);
			wppCUnit.setProdId(prod_id);
			wppCUnit.setEqptId(cTproductHis.getEqpt_id());
			wppCUnit.setUnitEqptId(cTproductHis.getUnit_eqpt_id());
			wppCUnit.setEqptPortId(cTproductHis.getEqpt_port_id());
			wppCUnit.setRecipeId(cTproductHis.getRecipe_id());
			wppCUnit.setAcRecipeId(cTproductHis.getAc_recipe_id());
			// evt_cate
			wppCUnit.setEvtCate("etl");
			wppCUnit.setEvtUsr("etl");
			wppCUnit.setInTimestamp(cTproductHis.getIn_timestamp());
			wppCUnit.setOutTimestamp(cTproductHis.getOut_timestamp());
			wppCUnit.setEvtTimestamp(cTproductHis.getOut_timestamp());
			// evt_note
			wppCUnit.setMesTimestamp(cTproductHis.getMes_timestamp());
			wppCUnit.setLotId(cTproductHis.getLot_id());
			wppCUnit.setCarrierName(cTproductHis.getCarrier_name());
			wppCUnit.setPosition(cTproductHis.getPosition());
			wppCUnit.setTraceLevel(cTproductHis.getTrace_level());
			wppCUnit.setProd_spec_ver(cTproductHis.getProd_spec_ver());
			wppCUnit.setLink_key(cTproductHis.getLink_key());
			wppCUnit.setOpeTblName("wpp_cunit_his");

			//modify by LynnSea

			Timestamp trackOutTimestamp = wppCUnit.getOutTimestamp();

			//得到mysql中设定的白班和夜班的开始结束时间
			//final String shfName = getShfNameProc(trackOutTimestamp);
			final String shfName =isDayShift(trackOutTimestamp, shfTimeMap.get("strDayShiftStartTime"),
					shfTimeMap.get("strDayShiftEndTime")) ? "Day" : "Night";
			// String hql;
			final String shopId = "3";

			//从m_shf_d表中查询出来shfId和shfKey ,并赋值shfKeyFk , shfId
			String shfId =shfIdMap.get(shfName+"_"+shopId);
			wppCUnit.setShfId(shfId);
			/*hql = "from MShfD where shfName = '" + shfName + "' and shop_key =' " + shopId + "'";
			final MShfD mShfD = dao2.uniqueResult(MShfD.class, hql);
			if (mShfD != null) {
				wppCUnit.setShfId(mShfD.getShfId());
//                wppAshtOpe.setShfKeyFk(mShfD.getShfKey());
			}*/

			//判断日期归属，白班和夜班存的是同一天
			//caldDate,caldKey

			final LocalDateTime localDateTime = trackOutTimestamp.toLocalDateTime();
			LocalDate localDate = LocalDate.ofYearDay(localDateTime.getYear(), localDateTime.getDayOfYear());

			if (StringUtils.equalsIgnoreCase(shfName, "Night")) {
				if (localDateTime.getHour() < 12 ) {
					localDate = localDate.plusDays(-1);
				}
			}
			wppCUnit.setCaldDate(java.sql.Date.valueOf(localDate));

			//判断小时，
			//并赋值给hourKeyFk,hourId

			/*hql = "from MHourD";
			final List<MHourD> mHourDList = dao2.find(MHourD.class, hql);*/
			final MHourD mHourD = calcHourProc(trackOutTimestamp, mHourDList);
			if (mHourD != null) {
				wppCUnit.setHourKeyFk(mHourD.getHourKey());
			}
			try {
				rabbitTemplate.convertAndSend("qmsExchange", "wpp_cunit_his", JacksonUtil.toJSONStr(wppCUnit));
			} catch (Exception e) {
				e.printStackTrace();
			}
//			 dao2.update(wppCUnit);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void saveAUnit(CtProductLocationHis cTproductHis, HashMap<String, Integer> shops,
			HashMap<String, Integer> opes, HashMap<String, Integer> prods,List<MHourD> mHourDList,Map<String,String> shfTimeMap,Map<String,String> shfIdMap) {
		String prod_id = cTproductHis.getProd_id();
		String ope_id = cTproductHis.getOpe_id();
		String shop_id = cTproductHis.getShop_id();
		String sub_eqpt_id = cTproductHis.getSub_eqpt_id();
		String glass_id = cTproductHis.getGlass_id();

		try {

			int prodKey = 0;
			String proKey = shop_id + prod_id;
			Integer pKey = prods.get(proKey);
			if (prod_id == null || prod_id.length() <= 0) {
				prod_id = "no";
			}
			if (pKey != null && pKey > 0) {
				prodKey = pKey;
			}
			int opeKey = 0;
			Integer oKey = opes.get(ope_id);
			if (oKey != null && oKey > 0) {
				opeKey = oKey;
			}
			int shopKey = 0;
			Integer sKey = shops.get(shop_id);
			if (sKey != null && sKey > 0) {
				shopKey = sKey;
			}
			WppAunitHis wppAUnit = new WppAunitHis();
			// base_id
			if (glass_id.length() == 10) {
				wppAUnit.setBaseId("G");
			} else if (glass_id.length() == 12) {
				wppAUnit.setBaseId("P");
			} else {
				return;
			}

			String unq_seq_id = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
			if (sub_eqpt_id == null || sub_eqpt_id == "") {
				wppAUnit.setSubEqptId("no");
			} else {
				wppAUnit.setSubEqptId(sub_eqpt_id);
			}

			wppAUnit.setProdKey(prodKey);
			wppAUnit.setShopKeyFk(shopKey);
			wppAUnit.setOpeKey(opeKey);

			wppAUnit.setUnqSeqId(unq_seq_id);
			wppAUnit.setEtlTimestamp(Timestamp.valueOf(LocalDateTime.now()));
			wppAUnit.setEtlEventNode(InetAddress.getLocalHost().getHostAddress());
			wppAUnit.setEtlEventName(InetAddress.getLocalHost().getHostName());
			// etl_evt_seq_id
			wppAUnit.setEtlEvtSeqId(unq_seq_id);
			wppAUnit.setGlassId(glass_id);
			wppAUnit.setOpeId(ope_id);
			wppAUnit.setShopId(shop_id);
			wppAUnit.setProdId(prod_id);
			wppAUnit.setEqptId(cTproductHis.getEqpt_id());
			wppAUnit.setUnitEqptId(cTproductHis.getUnit_eqpt_id());
			wppAUnit.setEqptPortId(cTproductHis.getEqpt_port_id());
			wppAUnit.setRecipeId(cTproductHis.getRecipe_id());
			wppAUnit.setAcRecipeId(cTproductHis.getAc_recipe_id());
			// evt_cate
			wppAUnit.setEvtCate("etl");
			wppAUnit.setEvtUsr("etl");
			wppAUnit.setInTimestamp(cTproductHis.getIn_timestamp());
			wppAUnit.setOutTimestamp(cTproductHis.getOut_timestamp());
			wppAUnit.setEvtTimestamp(cTproductHis.getOut_timestamp());
			// evt_note
			wppAUnit.setMesTimestamp(cTproductHis.getMes_timestamp());
			wppAUnit.setLotId(cTproductHis.getLot_id());
			wppAUnit.setCarrierName(cTproductHis.getCarrier_name());
			wppAUnit.setPosition(cTproductHis.getPosition());
			wppAUnit.setTraceLevel(cTproductHis.getTrace_level());
			wppAUnit.setProd_spec_ver(cTproductHis.getProd_spec_ver());
			wppAUnit.setLink_key(cTproductHis.getLink_key());
//			 dao2.update(wppAUnit);
			wppAUnit.setOpeTblName("wpp_aunit_his");

			//modify by LynnSea

			Timestamp trackOutTimestamp = wppAUnit.getOutTimestamp();

			//得到mysql中设定的白班和夜班的开始结束时间
	//		final String shfName = getShfNameProc(trackOutTimestamp);
			final String shfName =isDayShift(trackOutTimestamp, shfTimeMap.get("strDayShiftStartTime"),
					shfTimeMap.get("strDayShiftEndTime")) ? "Day" : "Night";
			//String hql;
			final String shopId = "1";

			//从m_shf_d表中查询出来shfId和shfKey ,并赋值shfKeyFk , shfId
			/*hql = "from MShfD where shfName = '" + shfName + "' and shop_key =' " + shopId + "'";
			final MShfD mShfD = dao2.uniqueResult(MShfD.class, hql);*/
			String shfId =shfIdMap.get(shfName+"_"+shopId);
			wppAUnit.setShfId(shfId);
			/*if (mShfD != null) {
				wppAUnit.setShfId(mShfD.getShfId());
//                wppAshtOpe.setShfKeyFk(mShfD.getShfKey());
			}*/

			//判断日期归属，白班和夜班存的是同一天
			//caldDate,caldKey

			final LocalDateTime localDateTime = trackOutTimestamp.toLocalDateTime();
			LocalDate localDate = LocalDate.ofYearDay(localDateTime.getYear(), localDateTime.getDayOfYear());

			if (StringUtils.equalsIgnoreCase(shfName, "Night")) {
				if (localDateTime.getHour() < 12 ) {
					localDate = localDate.plusDays(-1);
				}
			}
			wppAUnit.setCaldDate(java.sql.Date.valueOf(localDate));

//            final MCaldD mCaldD = calcCaldProc(trackOutTimestamp, shfName, dayShiftFlg ? strDayShiftStartTime : strNightShiftStartTime,
//                    dayShiftFlg ? strDayShiftEndTime : strNightShiftEndTime);
//            if (mCaldD != null) {
//                wppAshtOpe.setCaldDate(mCaldD.getCaldDate());
////                wppAshtOpe.setCaldKeyFk(mCaldD.getCaldKey());
//            }


			//判断小时，
			//并赋值给hourKeyFk,hourId

			/*hql = "from MHourD";
			final List<MHourD> mHourDList = dao2.find(MHourD.class, hql);*/
			final MHourD mHourD = calcHourProc(trackOutTimestamp, mHourDList);
			if (mHourD != null) {
//                wppAshtOpe.setHourId(mHourD.getHourNum());
				wppAUnit.setHourKeyFk(mHourD.getHourKey());
			}

			try {
				rabbitTemplate.convertAndSend("qmsExchange", "wpp_aunit_his", JacksonUtil.toJSONStr(wppAUnit));
			} catch (Exception e) {
				e.printStackTrace();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private String getShfNameProc(Timestamp trackOutTimestamp) {
		String hql = "from MBisDataD where dataCate = ? ";
		List<com.navi.loaddata.core.mysqlEntity.MBisDataD> wktmList = mysqlDao.list(com.navi.loaddata.core.mysqlEntity.MBisDataD.class, hql, "WKTM");

		com.navi.loaddata.core.mysqlEntity.MBisDataD dayShiftWktm = wktmList.stream().filter(w -> StringUtils.equalsIgnoreCase(w.getExt1(), "1")).findFirst().get();
		MBisDataD nightShiftWktm = wktmList.stream().filter(w -> StringUtils.equalsIgnoreCase(w.getExt1(), "2")).findFirst().get();

		String strDayShiftStartTime = dayShiftWktm.getExt2();
		String strDayShiftEndTime = dayShiftWktm.getExt3();
		String strNightShiftStartTime = nightShiftWktm.getExt2();
		String strNightShiftEndTime = nightShiftWktm.getExt3();

		//判断tracktime是属于白班还是夜班
		//Timestamp trackOutTimestamp = Timestamp.valueOf(LocalDateTime.now());

		final boolean dayShiftFlg = isDayShift(trackOutTimestamp, strDayShiftStartTime, strDayShiftEndTime);
		return dayShiftFlg ? "Day" : "Night";
	}
	//    private static String isDayShift(Timestamp trackOutTimesamp, String dayShfStartTime, String dayShfEndTime, String nightShfStartTime, String nightShfEndTime) {
	private static boolean isDayShift(Timestamp trackOutTimesamp, String dayShfStartTime, String dayShfEndTime) {

		//是否要判断夜班
		boolean dayShfFlg = isInDateTimeRange(trackOutTimesamp, dayShfStartTime, dayShfEndTime) ? true : false;

		return dayShfFlg;

	}

	/**
	 * 判断某个时间是否落在时间段内
	 *
	 * @param startTime         时间段开始时间
	 * @param endTime           时间段结束时间
	 * @param trackOutTimestamp 某个时间
	 * @return boolean
	 */
	private static boolean isInDateTimeRange(final Timestamp trackOutTimestamp, final String startTime, final String endTime) {


		final String[] startTimes = startTime.split(":");
		final String[] endTimes = endTime.split(":");

		final LocalDateTime startDatetime = LocalDateTime.of(LocalDate.now(), LocalTime.of(Integer.valueOf(startTimes[0]), Integer.valueOf(startTimes[1]), Integer.valueOf(startTimes[2])));
		LocalDateTime endDatetime = LocalDateTime.of(LocalDate.now(), LocalTime.of(Integer.valueOf(endTimes[0]), Integer.valueOf(endTimes[1]), Integer.valueOf(endTimes[2])));

		if (endDatetime.isBefore(startDatetime)) {
			endDatetime = endDatetime.plusDays(1);
		}

		final LocalDateTime trackOutTime = LocalDateTime.ofInstant(trackOutTimestamp.toInstant(), ZoneId.systemDefault());

		return trackOutTime.isAfter(startDatetime) && trackOutTime.isBefore(endDatetime);

	}

	private static MHourD calcHourProc(final Timestamp trackOutTimestamp, List<MHourD> mHourDList) {
		/*return mHourDList.parallelStream().filter(mHourD -> {
			final String timeIvl = mHourD.getTimeIvl();
			final String[] timeLvls = timeIvl.split("~");
			return isInTimeRange(trackOutTimestamp, timeLvls[0], timeLvls[1]);
		}).findFirst().get();*/   //ava.util.NoSuchElementException: No value present
		Optional ope;
		ope = mHourDList.parallelStream().filter(mHourD -> {
			final String timeIvl = mHourD.getTimeIvl();
			final String[] timeLvls = timeIvl.split("~");
			return isInTimeRange(trackOutTimestamp, timeLvls[0], timeLvls[1]);
		}).findFirst();
		if(ope.isPresent()){
			return   (MHourD)ope.get();
		}else
		return null;
	}

	private static boolean isInTimeRange(final Timestamp trackOutTimestamp, final String startTime, final String endTime) {

		LocalDateTime localDateTime = LocalDateTime.ofInstant(trackOutTimestamp.toInstant(), ZoneId.systemDefault());
		final LocalTime trackOutTime = localDateTime.toLocalTime();
		final String[] startTimes = startTime.split(":");
		final String[] endTimes = endTime.split(":");
		final LocalTime localStartTime = LocalTime.of(Integer.valueOf(startTimes[0]), Integer.valueOf(startTimes[1]));
		final LocalTime localtEndTime = LocalTime.of(Integer.valueOf(endTimes[0]), Integer.valueOf(endTimes[1]));
		return trackOutTime.isAfter(localStartTime) && trackOutTime.isBefore(localtEndTime);
	}

	private Map<String,String> getShfTimeProc() {
		Map<String,String> shfMap = new HashMap<String,String>();
		String hql = "from MBisDataD where dataCate = ? ";
		List<com.navi.loaddata.core.mysqlEntity.MBisDataD> wktmList = mysqlDao.list(com.navi.loaddata.core.mysqlEntity.MBisDataD.class, hql, "WKTM");

		com.navi.loaddata.core.mysqlEntity.MBisDataD dayShiftWktm = wktmList.stream().filter(w -> StringUtils.equalsIgnoreCase(w.getExt1(), "1")).findFirst().get();
		MBisDataD nightShiftWktm = wktmList.stream().filter(w -> StringUtils.equalsIgnoreCase(w.getExt1(), "2")).findFirst().get();

		String strDayShiftStartTime = dayShiftWktm.getExt2();
		String strDayShiftEndTime = dayShiftWktm.getExt3();
		String strNightShiftStartTime = nightShiftWktm.getExt2();
		String strNightShiftEndTime = nightShiftWktm.getExt3();

/*final boolean dayShiftFlg = isDayShift(trackOutTimestamp, strDayShiftStartTime, strDayShiftEndTime);
		return dayShiftFlg ? "Day" : "Night";*/
		shfMap.put("strDayShiftStartTime",strDayShiftStartTime);
		shfMap.put("strDayShiftEndTime",strDayShiftEndTime);
		shfMap.put("strNightShiftStartTime",strNightShiftStartTime);
		shfMap.put("strNightShiftEndTime",strNightShiftEndTime);
		return shfMap;

	}
	private Map<String,String> getShfMap(){
		Map<String,String> map =new HashMap<>();
		String shfHql = "from MShfD ";
		final List<MShfD> mShfD = dao2.find(MShfD.class, shfHql);
		mShfD.forEach(m->{
			String shfName = m.getShfName();
			Integer shopKey = m.getShopKey();
			String shfId = m.getShfId();
			map.put(shfName+"_"+shopKey,shfId);
		});
		return map;
	}
}
